# -*- coding: utf8 -*-
import re
from django import forms
from django.contrib.auth.models import User, Group
from django.template import Template, RequestContext
from django.shortcuts import render_to_response
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, Http404
from django.views.decorators.csrf import csrf_protect
from zenith.variables import *
from zenith.zenith_down.models import UserProfile, Record, FileRecord, Comment, UserToAccept
from datetime import date

class userChangeForm( forms.Form ):
	password = forms.CharField( min_length = 5, max_length = 20, widget = forms.PasswordInput, label = "New password:" )
	retype_password = forms.CharField( min_length = 5, max_length = 20, widget = forms.PasswordInput, label = "Retype your password:" )
	birthday = forms.DateField()
	email = forms.EmailField()
	gender = forms.ChoiceField( choices = GENDER_CHOICES )
	
	def clean_retype_password( self ):
		pwd1 = self.cleaned_data[ 'password' ]
		pwd2 = self.cleaned_data[ 'retype_password' ]
		if pwd1 != pwd2:
			raise forms.ValidationError( "两次密码输入不一致！" )
		return pwd1

class userRegistrationForm( forms.Form ):
	username = forms.CharField( min_length = 5, max_length = 20 )
	password = forms.CharField( min_length = 5, max_length = 20, widget = forms.PasswordInput )
	retype_password = forms.CharField( min_length = 5, max_length = 20, widget = forms.PasswordInput, label = "Retype your password:" )
	birthday = forms.DateField()
	email = forms.EmailField()
	gender = forms.ChoiceField( choices = GENDER_CHOICES )

	def clean_username( self ):
		usernm = self.cleaned_data[ 'username' ]
		if not usernm.isalnum():
			raise forms.ValidationError( "用户名含非法字符（即除字母数字之外的）" )
		try:
			existing = User.objects.get( username__iexact = usernm )
		except User.DoesNotExist:
			return usernm
		raise forms.ValidationError( "用户名已用。" )

	def clean_retype_password( self ):
		pwd1 = self.cleaned_data[ 'password' ]
		pwd2 = self.cleaned_data[ 'retype_password' ]
		if pwd1 != pwd2:
			raise forms.ValidationError( "两次密码输入不一致！" )
		return pwd1

class listAddForm( forms.Form ):
	parent = forms.ModelChoiceField( queryset = Record.objects.filter( rectype__exact = 'L' ) )
	abbr = forms.CharField( max_length = 128 )
	name = forms.CharField( max_length = 60 )
	description = forms.CharField( widget = forms.Textarea )

	ouser_write = forms.BooleanField( initial = True, required = False )
	ouser_read = forms.BooleanField( initial = True, required = False )
	ogroup_write = forms.BooleanField( initial = False, required = False )
	ogroup_read = forms.BooleanField( initial = True, required = False )
	others_write = forms.BooleanField( initial = False, required = False )
	others_read = forms.BooleanField( initial = False, required = False )

	def clean_parent( self ):
		p = self.cleaned_data[ 'parent' ]
		if p.rectype == 'F':
			raise forms.ValidationError( "异常错误！" )
		return p
	def clean_abbr( self ):
		a = self.cleaned_data[ 'abbr' ]
		if not a.isalnum():
			raise forms.ValidationError( "缩写中含有非法字符！" )
		try:
			Record.objects.get( abbr = self.cleaned_data[ 'abbr' ] )
		except Record.DoesNotExist:
			return a;
		else:
			raise forms.ValidationError

class fileAddForm( forms.Form ):
	parent = forms.ModelChoiceField( queryset = Record.objects.filter( rectype__exact = 'L' ) )
	abbr = forms.CharField( max_length = 128 )
	name = forms.CharField( max_length = 60 )
	description = forms.CharField( widget = forms.Textarea )
	file_data = forms.FileField()

	ouser_write = forms.BooleanField( initial = True, required = False )
	ouser_read = forms.BooleanField( initial = True, required = False )
	ogroup_write = forms.BooleanField( initial = False, required = False )
	ogroup_read = forms.BooleanField( initial = True, required = False )
	others_write = forms.BooleanField( initial = False, required = False )
	others_read = forms.BooleanField( initial = False, required = False )

@csrf_protect
@login_required
def fileAdd( request ):
	this = dict()
	this[ 'name' ] = request.user.username
	if request.method == 'POST':
		form = fileAddForm( request.POST, request.FILES )
		if form.is_valid():
			cd = form.cleaned_data
			f = request.FILES[ 'file_data' ]
			print f
			rec = Record()
			rec.abbr = cd[ 'abbr' ]
			rec.name = cd[ 'name' ]
			rec.parent = cd[ 'parent' ]
			rec.rectype = 'L'
			rec.description = cd[ 'description' ]
			rec.ouser_write = cd[ 'ouser_write' ]
			rec.ouser_read = cd[ 'ouser_read' ]
			rec.ogroup_write = cd[ 'ogroup_write' ]
			rec.ogroup_read = cd[ 'ogroup_read' ]
			rec.others_write = cd[ 'others_write' ]
			rec.others_read = cd[ 'others_read' ]
			rec.owner_user = request.user
			rec.start_date = date.today()
			rec.save()
			filerec = FileRecord()
			filerec.display_name = f.name
			filerec.file_name = f.get_filename()
			filerec.record = rec
			filerec.mimetype = f.content_type
			filerec.save()
			print form
			return render_to_response( 'showmessage.html',
				{ 'title' : '成功！',
				  'message' : '成功添加文件',
				  'this' : this },
				context_instance = RequestContext( request ) )
	else:
		try:
			ref = request.META[ 'HTTP_REFERER' ]
		except KeyError:
			pk = None
		else:
			m = re.search( r'file_list/(.+)/$', ref ).group( 1 )
			if m:
				try:
					p = Record.objects.get( abbr = m )
				except Record.DoesNotExist:
					pass
				else:
					if p.rectype == 'L':
						pk = p.id
		form = fileAddForm( initial = { 'parent' : pk } )
	return render_to_response( 'fileadd.html',
		{ 'file_add_form' : form,
		  'this' : this },
		RequestContext( request ) )

@csrf_protect
@login_required
def listAdd( request ):
	this = dict()
	this[ 'name' ] = request.user.username
	if request.method == 'POST':
		form = listAddForm( request.POST )
		if form.is_valid():
			cd = form.cleaned_data
			rec = Record()
			rec.abbr = cd[ 'abbr' ]
			rec.name = cd[ 'name' ]
			rec.parent = cd[ 'parent' ]
			rec.rectype = 'L'
			rec.description = cd[ 'description' ]
			rec.ouser_write = cd[ 'ouser_write' ]
			rec.ouser_read = cd[ 'ouser_read' ]
			rec.ogroup_write = cd[ 'ogroup_write' ]
			rec.ogroup_read = cd[ 'ogroup_read' ]
			rec.others_write = cd[ 'others_write' ]
			rec.others_read = cd[ 'others_read' ]
			rec.owner_user = request.user
			rec.start_date = date.today()
			rec.save()
			return render_to_response( 'showmessage.html',
				{ 'title' : '成功！',
				  'message' : '成功添加列表',
				  'this' : this },
				context_instance = RequestContext( request ) )
	else:
		try:
			ref = request.META[ 'HTTP_REFERER' ]
		except KeyError:
			pk = None
		else:
			m = re.search( r'file_list/(.+)/$', ref ).group( 1 )
			if m:
				try:
					p = Record.objects.get( abbr = m )
				except Record.DoesNotExist:
					pass
				else:
					if p.rectype == 'L':
						pk = p.id
		form = listAddForm( initial = { 'parent' : pk } )
	return render_to_response( 'listadd.html',
		{ 'list_add_form' : form,
		  'this' : this },
		RequestContext( request ) )

def getFileAddress( request, req_file_abbr ):
	try:
		r = Record.objects.get( abbr = req_file_abbr )
	except Record.DoesNotExist:
		raise Http404
	if r.rectype == 'L':
		raise Http404
	if r.others_read or r.ouser_read and request.user == r.owner_user or r.ogroup_read and request.user.groups.all() & r.owner_groups.all():
		return render_to_response( 'showmessage.html',
			{ 'title' : '无权访问',
			  'message' : '您无权访问该页...'
			} )
	try:
		dk = DownKey.objects.get( record = r, user = request.user )
	except DownKey.DoesNotExist:
		f = FileRecord.objects.get( record = r )
		dk = DownKey( record = r, user = request.user, key = md5_constructor( datetime.now + req_file_abbr + f.display_name ) )
		f.down_times = f.down_times + 1
		f.save()
		dk.save()
	return HttpResponseRedirect( '/zenith/serve_file/' + dk.key + '/' )

def serveFile( request, req_down_key ):
	try:
		dk = DownKey.objects.get( key = req_down_key )
	except DownKey.DoesNotExist:
		raise Http404
	f = FileRecord.objects.get( record = dk.record )
	r = HttpResponse( mimetype = 'application/octet-stream' )
	r[ 'Content-Disposition' ] = 'attachment; filename=' + f.display_name
	r[ 'X-Accel-Redirect' ] = '/zen_file/' + f.file_name
	return r

@csrf_protect
def userRegistration( request ):
	if request.method == 'POST':
		form = userRegistrationForm( request.POST )
		if form.is_valid():
			cd = form.cleaned_data
			user = User.objects.create_user( cd[ 'username' ], cd[ 'email' ], cd[ 'password' ] )
			profile = UserProfile()
			profile.user = user
			profile.gender = cd[ 'gender' ]
			profile.birthday = cd[ 'birthday' ]
			profile.save()
			return render_to_response( 'showmessage.html',
				{ 'title' : '成功',
				  'message' : '注册成功' },
				context_instance = RequestContext( request ) )
	else:
		form = userRegistrationForm()

	return render_to_response( 'userregistration.html',
		{ 'user_registration_form' : form },
		context_instance = RequestContext( request ) )

def userProfile( request, req_user_name ):
	try:
		user = User.objects.get( username = req_user_name )
	except User.DoesNotExist:
		raise Http404
	this = dict()
	profile = user.get_profile()
	this[ 'name' ] = user.username
	this[ 'email' ] = user.email
	this[ 'birthday' ] = profile.birthday
	this[ 'gender' ] = profile.gender
	this[ 'group' ] = user.groups.all()
	return render_to_response( 'userprofile.html',
		{ 'this' : this } )

@login_required
@csrf_protect
def userChange( request, req_user_name ):
	if req_user_name != request.user.username:
		raise Http404
	this = dict()
	this[ 'name' ] = req_user_name
	user = User.objects.get( username = req_user_name )
	profile = user.get_profile()
	if request.method == 'POST':
		form = userChangeForm( request.POST )
		if form.is_valid():
			cd = form.cleaned_data
			user.set_password( cd[ 'password' ] )
			profile.birthday = cd[ 'birthday' ]
			profile.gender = cd[ 'gender' ]
			return render_to_response( 'showmessage.html',
				{ 'title' : '成功',
				  'message' : '修改成功' } )
	else:
		form = userChangeForm()
		form.gender = profile.gender
		form.email = user.email
		form.birthday = profile.birthday
	return render_to_response( 'userchange.html',
		{ 'user_change_form' : form,
		  'this' : this },
		context_instance = RequestContext( request ) )
@login_required
def fileList( request, rec_name ):
	try:
		record = Record.objects.get( abbr = rec_name )
	except Record.DoesNotExist:
		raise Http404
	if not( record.others_read or ouser_read and request.user == record.owner_user or ogroup_read and request.user.groups & record.owner_groups ):
		return render_to_response( 'showmessage.html',
			{ 'title' : '无权访问',
			  'message' : '您无权访问该页...'
			} )
	this = dict()
	if record.rectype == 'L':
		rec_list = Record.objects.filter( parent__exact = record )
		this[ 'name' ] = record.name
		this[ 'owner' ] = record.owner_user
		this[ 'parent' ] = record.parent.abbr
		this[ 'startdate' ] = record.start_date
		this[ 'description' ] = record.description
		return render_to_response( 'displaylist.html',
			{ 'this' : this,
			  'rec_list' : rec_list } )
	else:
		rel_file = FileRecord.objects.get( record__exact = record )
		this[ 'name' ] = record.name
		this[ 'abbr' ] = record.abbr
		this[ 'owner' ] = record.owner_user
		this[ 'startdate' ] = record.start_date
		this[ 'description' ] = record.description
		this[ 'display_name' ] = rel_file.display_name
		return render_to_response( 'displayfile.html',
			{ 'this' : this } )
